#include "SByte.h"
#include <iomanip>

#include "SNumber.h"

SByteSp SByte::Parse(string s)
{
	trim(s);

	// Check the syntax:
	//  - from 1 to 3 digits ( 0, 10, 100, 999 )
	//  - a "0x" followed by 1 or 2 exadecimal digit ( 0x0, 0xA, 0xab, 0xF6 )

	regex reg_dec("\\d{1,3}");                 // Decimal value
	regex reg_hex("0x[0-9a-fA-F]{1,2}");       // Hexadecimal value
	bool syntax_error = false;
	int n;
	
	if ( regex_match(s, reg_dec) )
	{
		// Decimal conversion				
		try
		{
			n = lexical_cast<int>( s );
		}
		catch(bad_lexical_cast&)
		{
			syntax_error = true;
		}
	}
	else if ( regex_match(s, reg_hex) )
	{			
		// Hexadecimal conversion
		n = Utility::HexToDec( s.substr(2) );
	}
	else
	{
		syntax_error = true;
	}
	
	// Test if the value is in the range [0, 255]
	if ( n < 0 || n > 255 )
	{
		syntax_error = true;
	}

	if ( syntax_error )
	{
		throw SParseException("Syntax error: " + s + " is not a SByte literal.");
	}

	return SByte::Create( (unsigned char) n);
}

string SByte::ToString()
{
	return ToString(""); 
}

string SByte::ToString( string format )
{
	ostringstream os;

	//if ( format.empty() || format == "d")  // decimal format
	//{
	//	os << (int) value;
	//}
	//else if ( format == "x")  // exadecimal format
	//{
	//	os << "0x" << setfill('0') << setw(2) << uppercase << hex << (int) value;
	//}
	//else if ( format == "nx")  // exadecimal format without 0x
	//{
	//	os << setfill('0') << setw(2) << uppercase << hex << (int) value;
	//}
	//else if ( format == "a")  // ascii format
	//{
		//char c = value;
		//if ( Utility::IsPrintable(c))
		//{
		//	os << c;
		//}
		//else
		//{
		//	os << ".";
		//}
	//}

	if ( format != "a" )
	{
		SNumberSp n = SNumber::Create(value);
		os << n->ToString(format);
	}
	else
	{
		char c = value;

		if ( Utility::IsPrintable(c))
		{
			os << c;
		}
		else
		{
			os << ".";
		}
	}

	return os.str();
}

SByteSp SByte::Create( unsigned char value )
{
	return SByteSp(new SByte(value));
}